﻿
using Castle.Core.Internal;
using Coldairarrow.Business.Interface;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.Interface;
using Coldairarrow.Util;
using Microsoft.Extensions.Options;
using NetTopologySuite.Index.HPRtree;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics.Tracing;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Net;
using System.Reflection.Metadata;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using static org.apache.zookeeper.ZooDefs;

namespace Coldairarrow.Business.Interface
{
    public class PL_InventoryInterfaceBusiness : PLInterface_BaseBusiness, IJob_Business, ITransientDependency
    {
        //接口信息
        public Base_InterfaceOption PL_Query;
        public PL_InventoryInterfaceBusiness()
        {
            this.InterfaceName = "PL库存";
            //索引字段
            this.MapFields = GetMapField("PL_Query");

            //获取此接口的所有API信息
            this.interfaceOption = SqlDb.GetListBySql<Base_InterfaceOption>(@$"SELECT * FROM  Base_InterfaceOption(NOLOCK) WHERE Name='{InterfaceName}' ");
            PL_Query = this.interfaceOption.Where(x => x.OperateType == "PL_Query").First();

            //查询执行前的事件
            this.BeforeQueryEvent += InterfaceBusiness_BeforeQueryEvent;
            //查询执行中的事件
            this.OnQueryEvent += InterfaceBusiness_OnQueryEvent;
            //查询执行中的事件
            this.AfterQueryEvent += InterfaceBusiness_AfterQueryEvent;

            //执行非查询请求中的事件
            this.OnNoQueryEvent += InterfaceBusiness_OnNoQueryEvent;

        }

        /// <summary>
        /// 执行非查询请求中事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="PL_NoQueryEventArgs"></param>
        private void InterfaceBusiness_OnNoQueryEvent(object sender, PL_NoQueryEventArgs queryEventArgs)
        {
            //API请求是否成功
            //queryEventArgs.Success = queryEventArgs.Result["success"].ToString().ToBool();
        }

        /// <summary>
        /// 查询执行前的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_BeforeQueryEvent(object sender, PL_QueryEventArgs queryEventArgs)
        {
            try
            {

                PL_WarehouseDTOInterfaceBusiness pL_Warehouse = new PL_WarehouseDTOInterfaceBusiness();
                List<PL_Warehouse> warehouseList = pL_Warehouse.Query<PL_Warehouse>(pL_Warehouse.PL_Query, pL_Warehouse.SqlDb);
                PL_ReqDTO baseReq = new PL_ReqDTO();
                //获取配置参数
                this.SqlDb._conStrings[0] = JsonSettingHelper.GetSetting("Database:BaseDb:ConnectionString");
                var parameters = this.SqlDb.GetListBySql<Base_ConfigParameter>(@$"SELECT * FROM  Base_ConfigParameter(NOLOCK) WHERE Code='Packlin'");
                baseReq.token = parameters.Where(x => x.Name == "Token").First().Value;
                baseReq.userId = parameters.Where(x => x.Name == "UserId").First().Value;
                queryEventArgs.CustomData = baseReq;
                queryEventArgs.CustomData2 = warehouseList;
            }
            catch (Exception ex)
            {
                AddLog(SqlDb, ex.Message, InterfaceName, "erro", "");
            }
        }

        /// <summary>
        /// 查询中的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_OnQueryEvent(object sender, PL_QueryEventArgs queryEventArgs)
        {
            //设置还未查询的仓库
            List<PL_Warehouse> warehouseList = (List<PL_Warehouse>)queryEventArgs.CustomData2;
            //json参数
            PL_ReqDTO data = (PL_ReqDTO)queryEventArgs.CustomData;
            data.warehouse_code = warehouseList[0].warehous_code;
            data.authorization = GenerateAuthorizationSecret(data.userId, data.token);
            queryEventArgs.reqData = GetJsonData(queryEventArgs.APINodes, queryEventArgs.ParentNode, data);

        }

        /// <summary>
        /// 查询执行后的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_AfterQueryEvent(object sender, PL_QueryEventArgs queryEventArgs)
        {

            try
            {
                //将查询后的数据转换成对应格式的数据
                PL_InventoryDTO result = (PL_InventoryDTO)JsonConvert.DeserializeObject<PL_InventoryDTO>(queryEventArgs.ResultStr);
                if (result.code == 200 || result.code == 4102)
                {
                    List<PL_Warehouse> warehouseList = (List<PL_Warehouse>)queryEventArgs.CustomData2;
                    warehouseList.RemoveAt(0);
                    queryEventArgs.CustomData2 = warehouseList;
                    if (warehouseList.Count == 0)
                    {
                        queryEventArgs.Page.Complete = true;
                    }

                    queryEventArgs.Success = true;
                    queryEventArgs.Rows = result.data.IsNullOrEmpty() ? null : result.data.list;
                }
                else
                { queryEventArgs.Success = false; }

            }
            catch (Exception ex)
            {
                queryEventArgs.Success = false;
                AddLog(SqlDb, ex.Message, InterfaceName, "erro", "");
            }

        }

        /// <summary>
        /// 执行增删改查业务
        /// </summary>
        public async void ExecuteInterface()
        {
            List<PL_Inventory.List> invList = await this.QueryAsync<PL_Inventory.List>(this.PL_Query, SqlDb);



        }

        /// <summary>
        /// 任务
        /// </summary>
        public void Job()
        {
            ExecuteInterface();
        }

        /// <summary>
        /// 生成API的认证吗
        /// </summary>
        /// <param name="clientId">客户ID</param>
        /// <param name="clientSecret">Token</param>
        /// <returns></returns>
        private string GenerateAuthorizationSecret(string clientId, string clientSecret)
        {
            // 1. 获取当前时间戳（秒级）
            long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

            // 2. 拼接clientSecret和时间戳
            string clientStr = clientSecret + timestamp.ToString();

            // 3. 生成16字节IV（模拟Java的UUID.randomUUID()行为）
            string iv = GenerateIv();

            // 4. 使用AES-256-CBC加密
            string encrypted = Encrypt(clientStr, clientSecret, iv);

            // 5. 拼接IV和加密结果并进行Base64编码
            string ivPlusEncrypted = iv + encrypted;
            byte[] ivPlusEncryptedBytes = Encoding.UTF8.GetBytes(ivPlusEncrypted);
            string encryptToken = Convert.ToBase64String(ivPlusEncryptedBytes);

            // 6. 生成最终授权令牌
            return $"{clientId}-{encryptToken}-{timestamp}";
        }

        /// <summary>
        /// 获取16位的iv
        /// </summary>
        /// <returns></returns>
        private string GenerateIv()
        {
            // 模拟Java的UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16)
            return Guid.NewGuid().ToString("N").Substring(0, 16);
        }
        /// <summary>
        /// 生成认证码
        /// </summary>
        /// <param name="plainText"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        private string Encrypt(string plainText, string key, string iv)
        {
            using (Aes aes = Aes.Create())
            {
                // 注意：Java代码直接使用key的字节作为密钥，没有进行密钥派生
                // 所以这里我们也直接使用UTF8编码的字节
                // 如果key不是32字节，AES会抛出异常
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = Encoding.UTF8.GetBytes(iv);
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7; // PKCS7等同于Java的PKCS5Padding

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
                        cs.Write(plainBytes, 0, plainBytes.Length);
                        cs.FlushFinalBlock();
                        return Convert.ToBase64String(ms.ToArray());
                    }
                }
            }
        }
    }

}
